package com.lyf.scm.plan.domain.service.impl;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.lyf.scm.common.constants.CommonConstants;
import com.lyf.scm.common.enums.*;
import com.lyf.scm.common.model.BaseNormalDTO;
import com.lyf.scm.common.model.BaseSearchDTO;
import com.lyf.scm.common.model.ExcelExportDataDTO;
import com.lyf.scm.common.model.SalesPlanSelectDTO;
import com.lyf.scm.common.util.AdvancedSearchUtil;
import com.lyf.scm.common.util.ExcelExportUtil;
import com.lyf.scm.common.util.date.MyDateUtil;
import com.lyf.scm.common.util.style.DirectlyDifferinCellWriterHandler;
import com.lyf.scm.plan.api.dto.*;
import com.lyf.scm.plan.domain.convertor.SalePlanDirectlyDifferinSelectConvertor;
import com.lyf.scm.plan.domain.remote.basedata.dto.StoreDTO;
import com.lyf.scm.plan.domain.remote.basedata.facade.BaseDataFacade;
import com.lyf.scm.plan.domain.remote.item.dto.SkuUnitDTO;
import com.lyf.scm.plan.domain.remote.item.facade.ItemCoreFacade;
import com.lyf.scm.plan.domain.remote.purchase.dto.PlanPoInfoDTO;
import com.lyf.scm.plan.domain.remote.purchase.dto.PlanPoQueryDTO;
import com.lyf.scm.plan.domain.remote.purchase.facade.PurchaseFacade;
import com.lyf.scm.plan.domain.repository.*;
import com.lyf.scm.plan.domain.service.SalePlanDirectlyDifferinService;
import com.lyf.scm.plan.insfrastructure.db.dataobject.SalesPlanSelectDO;
import com.lyf.scm.plan.insfrastructure.db.dataobject.bigdata.DirectlyDifferinInDO;
import com.lyf.scm.plan.insfrastructure.db.dataobject.bigdata.DirectlyDifferinUpDO;
import com.rome.arch.core.exception.RomeException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

import static com.lyf.scm.common.util.BatchHandlerUtil.splitTo;
import static com.lyf.scm.plan.domain.util.BigDataCacheUtil.*;
import static java.util.stream.Collectors.groupingBy;

/**
 * 直营预测计划_目标与销售计划差异
 *
 * @author wangchlei
 * @date 2020/08/05
 */
@Slf4j
@Service
public class SalePlanDirectlyDifferinServiceImpl implements SalePlanDirectlyDifferinService {
    @Resource
    private SalePlanDirectlyDifferinRepository salePlanDirectlyDifferinRepository;
    @Resource
    private SalePlanDirectlyDifferinSelectConvertor salePlanDirectlyDifferinSelectConvertor;
    @Resource
    private ItemCoreFacade itemCoreFacade;
    @Resource
    private GmvTargetRepository gmvTargetRepository;
    @Resource
    private PurchaseFacade purchaseFacade;
    @Resource
    private BaseDataFacade baseDataFacade;
    @Resource
    private RoleAuthorityAreaRepository roleAuthorityAreaRepository;
    @Resource
    private OperationLogRecordRepository operationLogRecordRepository;
    @Resource
    private SalesPlanEsRepository esRepository;

    /**
     * 按条件查询直营预测计划_目标与销售计划差异(周)
     *
     * @param salePlanDirectlyDifferinDTO
     * @return {@link PageInfoExpandDTO <SalePlanDirectlyDifferinInfoDTO>}
     **/
    @Override
    public PageInfoExpandDTO<SalePlanDirectlyDifferinInfoDTO> listWeekBySelective(SalePlanDirectlyDifferinDTO salePlanDirectlyDifferinDTO) {
        //校验角色区域权限是否正确（同时赋值区域搜索条件）
        this.checkRoleArea(salePlanDirectlyDifferinDTO);
        //校验是否需要gmv指标
        this.checkGmv(salePlanDirectlyDifferinDTO);
        SalesPlanSelectDO salesPlanSelectDO = salePlanDirectlyDifferinSelectConvertor.dtoToDO(salePlanDirectlyDifferinDTO);
        //非分页查询
        List<SalePlanDirectlyDifferinInfoDTO> salePlanDirectlyDifferinInfoDTOs = salePlanDirectlyDifferinRepository.listByCycles(salesPlanSelectDO);
        if (CollectionUtils.isEmpty(salePlanDirectlyDifferinInfoDTOs)) {
            return new PageInfoExpandDTO<>();
        }
        //获取所有去重后的skuCode
        List<String> skuCodes = salePlanDirectlyDifferinInfoDTOs.stream().map(SalePlanDirectlyDifferinInfoDTO::getSkuCode).distinct().collect(Collectors.toList());
        Map<String, BigDecimal> map = this.getBaseSkuUnitRate(skuCodes, salePlanDirectlyDifferinDTO.getUnitType());
        //获取所有查询条件标识
        List<String> conditions = AdvancedSearchUtil.getConditions(salePlanDirectlyDifferinDTO);
        //统计不同维度时间周期的长度
        int elementsSize = AdvancedSearchUtil.getElementsSize(salePlanDirectlyDifferinDTO.getWeekDateList());
        //获取分页数据
        int startIndex = (salePlanDirectlyDifferinDTO.getPageNum() - 1) * salePlanDirectlyDifferinDTO.getPageSize();
        int endIndex = salePlanDirectlyDifferinDTO.getPageNum() * salePlanDirectlyDifferinDTO.getPageSize() - 1;
        //组下标
        AtomicInteger groupIndex = new AtomicInteger(0);
        //最终结果
        List<SalePlanDirectlyDifferinInfoDTO> pageList = new ArrayList<>();
        //获取聚合结果
        Map<String, BigDecimal> finalMap = map;
        Map<String, SalePlanDirectlyDifferinInfoDTO> polymerizationResult = salePlanDirectlyDifferinInfoDTOs.stream().collect(groupingBy(item -> AdvancedSearchUtil.fetchGroupKey(item, conditions), TreeMap::new, Collectors.collectingAndThen(Collectors.toList(), values -> {
            if (groupIndex.get() < startIndex || groupIndex.get() > endIndex) {
                groupIndex.incrementAndGet();
                return null;
            }
            //遍历每一组的集合，将对应参数聚合，然后赋值给第一个元素，将第一个元素返回
            List<BigDecimal> salesForecastAmounts = new ArrayList<>();
            List<BigDecimal> salesActualAmounts = new ArrayList<>();
            List<BigDecimal> salesActualQtys = new ArrayList<>();
            List<BigDecimal> salesForecastQtys = new ArrayList<>();
            values.forEach(item -> {
                if (finalMap.get(item.getSkuCode()) == null) {
                    throw new RomeException("999", "无法获取单位比例转换信息：" + "skuCode," + item.getSkuCode() + "; 单位类型" + SkuUnitTypeEnum.getNameByType(salePlanDirectlyDifferinDTO.getUnitType()));
                }
                salesForecastAmounts.addAll(Arrays.stream(item.getSalesForecastAmountStr().split(":")).map(BigDecimal::new).collect(Collectors.toList()));
                salesActualAmounts.addAll(Arrays.stream(item.getSalesActualAmountStr().split(":")).map(BigDecimal::new).collect(Collectors.toList()));
                salesForecastQtys.addAll(Arrays.stream(item.getSalesForecastQtyStr().split(":")).map(subItem -> new BigDecimal(subItem).divide(finalMap.get(item.getSkuCode()), 5, BigDecimal.ROUND_HALF_UP)).collect(Collectors.toList()));
                salesActualQtys.addAll(Arrays.stream(item.getSalesActualQtyStr().split(":")).map(subItem -> new BigDecimal(subItem).divide(finalMap.get(item.getSkuCode()), 5, BigDecimal.ROUND_HALF_UP)).collect(Collectors.toList()));
            });
            //总长度
            int totalSize = salesForecastAmounts.size();
            List<BigDecimal> salesForecastAmount = AdvancedSearchUtil.getMergeResult(salesForecastAmounts, elementsSize, totalSize);
            List<BigDecimal> salesActualAmount = AdvancedSearchUtil.getMergeResult(salesActualAmounts, elementsSize, totalSize);
            List<BigDecimal> salesForecastQty = AdvancedSearchUtil.getMergeResult(salesForecastQtys, elementsSize, totalSize);
            List<BigDecimal> salesActualQty = AdvancedSearchUtil.getMergeResult(salesActualQtys, elementsSize, totalSize);
            values.get(0).setSalesForecastAmount(salesForecastAmount);
            values.get(0).setSalesPlanAmount(salesForecastAmount);
            values.get(0).setSalesActualAmount(salesActualAmount);
            values.get(0).setSalesForecastQty(salesForecastQty);
            values.get(0).setSalesPlanQty(salesForecastQty);
            values.get(0).setSalesActualQty(salesActualQty);
            //赋值label标签
            this.setLable(values.get(0));
            //赋值查询条件
            AdvancedSearchUtil.setGroupAdvancedSearchCondition(values.get(0), conditions);
            pageList.add(values.get(0));
            groupIndex.incrementAndGet();
            return values.get(0);
        })));
        //判断是否需要查询GMV信息（如果需要就做处理）
        this.handelGmvInfo(salePlanDirectlyDifferinDTO, pageList, elementsSize);
        //设置实际收货量值
        this.setActualReceivedQty(salePlanDirectlyDifferinDTO, conditions, pageList, elementsSize, skuCodes);
        //获取分页数据
        PageInfoExpandDTO<SalePlanDirectlyDifferinInfoDTO> pageInfo = new PageInfoExpandDTO<>();
        pageInfo.setTotal(polymerizationResult.values().size());
        pageInfo.setList(pageList);
        pageInfo.setValidGmv(salePlanDirectlyDifferinDTO.getValidGmv());
        return pageInfo;
    }

    private void checkGmv(SalePlanDirectlyDifferinDTO salePlanDirectlyDifferinDTO) {
        //Gmv参数是否存在判断
        boolean isValidGmv = AdvancedSearchUtil.validGmvInfo(salePlanDirectlyDifferinDTO);
        //TODO 去除GMV
        salePlanDirectlyDifferinDTO.setValidGmv(false);
        this.setGvmParam(salePlanDirectlyDifferinDTO);
    }

    private void setGvmParam(SalePlanDirectlyDifferinDTO salePlanDirectlyDifferinDTO) {
        if (salePlanDirectlyDifferinDTO.getValidGmv()) {
            //gmv查询条件——————开始日期
            Date startDateOfMonth = DateUtil.beginOfMonth(salePlanDirectlyDifferinDTO.getStartTime());
            salePlanDirectlyDifferinDTO.setGmvStartDate(startDateOfMonth);
            //gmv查询条件——————截止日期
            Date gmvEndDate = DateUtil.beginOfDay(DateUtil.endOfMonth(salePlanDirectlyDifferinDTO.getEndTime()));
            salePlanDirectlyDifferinDTO.setGmvEndDate(gmvEndDate);
            //gmv截止日期所在月第一天
            Date beginDayOfLastMonth = DateUtil.beginOfMonth(gmvEndDate);
            //获取gmv开始时间所在月第一天
            Date start = salePlanDirectlyDifferinDTO.getGmvStartDate();
            Map<Date, BigDecimal> gmvMonthDays = new HashMap<>();
            while (start.compareTo(beginDayOfLastMonth) <= 0) {
                Date nextStart = DateUtil.offset(start, DateField.MONTH, 1);
                gmvMonthDays.put(start, BigDecimal.valueOf(DateUtil.betweenDay(start, nextStart, false)));
                start = nextStart;
            }
            Map<Date, BigDecimal> weekMonthDays = new HashMap<>();
            Map<Date, BigDecimal> subWeekMonthDays = new HashMap<>();
            Map<Date, Date> weekMonthDate = new HashMap<>();
            Map<Date, Date> subWeekMonthDate = new HashMap<>();
            //GMV计划查询月所对应天数
            salePlanDirectlyDifferinDTO.setGmvMonthDays(gmvMonthDays);
            salePlanDirectlyDifferinDTO.getWeekDateList().forEach(item -> {
                Date startTime = item.get("startTime");
                Date endTime = item.get("endTime");
                if (DateUtil.month(startTime) == DateUtil.month(endTime)) {
                    weekMonthDays.put(startTime, new BigDecimal("7"));
                    subWeekMonthDays.put(startTime, new BigDecimal("0"));
                    weekMonthDate.put(startTime, DateUtil.beginOfMonth(startTime));
                    subWeekMonthDate.put(startTime, null);
                } else {
                    weekMonthDays.put(startTime, BigDecimal.valueOf(DateUtil.between(startTime, DateUtil.endOfMonth(startTime), DateUnit.DAY, false) + 1));
                    subWeekMonthDays.put(startTime, BigDecimal.valueOf(DateUtil.between(DateUtil.endOfMonth(startTime), endTime, DateUnit.DAY, false) + 1));
                    weekMonthDate.put(startTime, DateUtil.beginOfMonth(startTime));
                    subWeekMonthDate.put(startTime, DateUtil.beginOfMonth(endTime));
                }
            });
            //每一周所在第一个月的日期
            salePlanDirectlyDifferinDTO.setWeekMonthDate(weekMonthDate);
            //每一周所在第二个月的日期
            salePlanDirectlyDifferinDTO.setSubWeekMonthDate(subWeekMonthDate);
            //每一周所在第一个月的天数
            salePlanDirectlyDifferinDTO.setWeekMonthDays(weekMonthDays);
            //每一周所在第二个月的天数
            salePlanDirectlyDifferinDTO.setSubWeekMonthDays(subWeekMonthDays);
        }
    }

    /**
     * 校验角色区域信息
     *
     * @param baseSearchDTO
     * @return void
     **/
    private void checkRoleArea(BaseSearchDTO baseSearchDTO) {
        //从角色区域权限表获取对应区域
        List<RoleAuthorityAreaDTO> roleAuthorityAreaDTOS = roleAuthorityAreaRepository.listByUserId(baseSearchDTO.getCreator());
        if (CollectionUtils.isEmpty(roleAuthorityAreaDTOS)) {
            throw new RomeException("999", "该角色的无任何区域权限");
        }
        //获取该角色的区域信息
        List<SalesPlanSelectDTO> salesPlanSelectDTOS = roleAuthorityAreaDTOS.stream().filter(item -> item.getChannelCode() == null || "".equals(item.getChannelCode())).map(item -> {
            SalesPlanSelectDTO salesPlanSelectDTO = new SalesPlanSelectDTO();
            if (item.getCountyCode() != null && !"".equals(item.getCountyCode())) {
                salesPlanSelectDTO.setLevel(CommonConstants.AREA_LEVEL_THREE);
                salesPlanSelectDTO.setCode(item.getCountyCode());
                return salesPlanSelectDTO;
            }
            if (item.getCityCode() != null && !"".equals(item.getCityCode())) {
                salesPlanSelectDTO.setLevel(CommonConstants.AREA_LEVEL_TWO);
                salesPlanSelectDTO.setCode(item.getCityCode());
                return salesPlanSelectDTO;
            }
            if (item.getProvinceCode() != null && !"".equals(item.getProvinceCode())) {
                salesPlanSelectDTO.setLevel(CommonConstants.AREA_LEVEL_ONE);
                salesPlanSelectDTO.setCode(item.getProvinceCode());
                return salesPlanSelectDTO;
            }
            throw new RomeException("999", "数据库角色区域权限有错误");
        }).collect(Collectors.toList());
        //将其统一到最低层级
        List<SalesPlanSelectDTO> roleAreas = baseDataFacade.getSubAreaCode(salesPlanSelectDTOS);
        //如果有查询条件
        if (!CollectionUtils.isEmpty(baseSearchDTO.getAreaCodeList())) {
            //将查询条件汇总到最低层级
            List<SalesPlanSelectDTO> searchAreas = baseDataFacade.getSubAreaCode(baseSearchDTO.getAreaCodeList());
            List<SalesPlanSelectDTO> result = null;
            if (searchAreas.get(0).getLevel() > roleAreas.get(0).getLevel()) {
                result = this.recursionLevel(roleAreas, searchAreas.get(0).getLevel());
                if (!result.containsAll(searchAreas)) {
                    throw new RomeException(ResponseMsg.FAIL_1906.getCode(), ResponseMsg.FAIL_1906.getMsg());
                }
            }
            if (searchAreas.get(0).getLevel().equals(roleAreas.get(0).getLevel())) {
                if (!roleAreas.containsAll(searchAreas)) {
                    throw new RomeException(ResponseMsg.FAIL_1906.getCode(), ResponseMsg.FAIL_1906.getMsg());
                }
            }
            if (searchAreas.get(0).getLevel() < roleAreas.get(0).getLevel()) {
                result = this.recursionLevel(searchAreas, roleAreas.get(0).getLevel());
                if (!roleAreas.containsAll(result)) {
                    throw new RomeException(ResponseMsg.FAIL_1906.getCode(), ResponseMsg.FAIL_1906.getMsg());
                }
            }
            setAreaSearch(searchAreas, baseSearchDTO);
        } else {
            setAreaSearch(roleAreas, baseSearchDTO);
        }
    }

    private void setAreaSearch(List<SalesPlanSelectDTO> areas, BaseSearchDTO baseSearchDTO) {
        if (CommonConstants.AREA_LEVEL_ONE.equals(areas.get(0).getLevel())) {
            baseSearchDTO.setProvinceCodeList(areas.stream().map(SalesPlanSelectDTO::getCode).distinct().collect(Collectors.toList()));
        }
        if (CommonConstants.AREA_LEVEL_TWO.equals(areas.get(0).getLevel())) {
            baseSearchDTO.setCityCodeList(areas.stream().map(SalesPlanSelectDTO::getCode).distinct().collect(Collectors.toList()));
        }
        if (CommonConstants.AREA_LEVEL_THREE.equals(areas.get(0).getLevel())) {
            baseSearchDTO.setCountyCodeList(areas.stream().map(SalesPlanSelectDTO::getCode).distinct().collect(Collectors.toList()));
        }
        if (CommonConstants.AREA_LEVEL_FOUR.equals(areas.get(0).getLevel())) {
            baseSearchDTO.setStoreCodeList(areas.stream().map(SalesPlanSelectDTO::getCode).distinct().collect(Collectors.toList()));
        }
    }

    private List<SalesPlanSelectDTO> recursionLevel(List<SalesPlanSelectDTO> searchAreas, Integer level) {
        List<String> codeList = searchAreas.stream().map(SalesPlanSelectDTO::getCode).collect(Collectors.toList());
        if (level.equals(CommonConstants.AREA_LEVEL_FOUR)) {
            List<StoreDTO> storeList = new ArrayList<>();
            if (searchAreas.get(0).getLevel().equals(CommonConstants.AREA_LEVEL_ONE)) {
                storeList = baseDataFacade.ListStoreByArea(codeList, CommonConstants.AREA_LEVEL_ONE, 1, 3000);
            }
            if (searchAreas.get(0).getLevel().equals(CommonConstants.AREA_LEVEL_TWO)) {
                storeList = baseDataFacade.ListStoreByArea(codeList, CommonConstants.AREA_LEVEL_TWO, 1, 3000);
            }
            if (searchAreas.get(0).getLevel().equals(CommonConstants.AREA_LEVEL_THREE)) {
                storeList = baseDataFacade.ListStoreByArea(codeList, CommonConstants.AREA_LEVEL_THREE, 1, 3000);
            }
            List<SalesPlanSelectDTO> areaList = storeList.stream().map(item -> {
                SalesPlanSelectDTO salesPlanSelectDTO = new SalesPlanSelectDTO();
                salesPlanSelectDTO.setCode(item.getCode());
                salesPlanSelectDTO.setLevel(level);
                return salesPlanSelectDTO;
            }).collect(Collectors.toList());
            return areaList;
        } else {
            if (searchAreas.get(0).getLevel() < level) {
                List<SalesPlanSelectDTO> areas = baseDataFacade.batchSearchByParentCode(codeList).stream().map(item -> {
                    SalesPlanSelectDTO salesPlanSelectDTO = new SalesPlanSelectDTO();
                    salesPlanSelectDTO.setCode(item.getCode());
                    salesPlanSelectDTO.setLevel(item.getLevel());
                    return salesPlanSelectDTO;
                }).collect(Collectors.toList());
                return this.recursionLevel(areas, level);
            }
        }
        return searchAreas;
    }

    /**
     * 图表数据接口(按区域)
     *
     * @param salePlanDirectlyDifferinDTO
     * @return {@link EChartsDTO}
     **/
    @Override
    public EChartsExpandDTO eChartsData(SalePlanDirectlyDifferinDTO salePlanDirectlyDifferinDTO) {
        //校验角色区域权限是否正确（同时赋值区域搜索条件）
        this.checkRoleArea(salePlanDirectlyDifferinDTO);
        //校验是否需要gmv指标
        this.checkGmv(salePlanDirectlyDifferinDTO);
        SalesPlanSelectDO salesPlanSelectDO = salePlanDirectlyDifferinSelectConvertor.dtoToDO(salePlanDirectlyDifferinDTO);
        List<SalePlanDirectlyDifferinInfoDTO> salePlanDirectlyDifferinInfoDTOs = salePlanDirectlyDifferinRepository.eChartsData(salesPlanSelectDO);
        if (CollectionUtils.isEmpty(salePlanDirectlyDifferinInfoDTOs)) {
            return new EChartsExpandDTO();
        }
        //获取所有去重后的skuCode
        List<String> skuCodes = salePlanDirectlyDifferinInfoDTOs.stream().map(SalePlanDirectlyDifferinInfoDTO::getSkuCode).distinct().collect(Collectors.toList());
        Map<String, BigDecimal> map = this.getBaseSkuUnitRate(skuCodes, salePlanDirectlyDifferinDTO.getUnitType());
        //统计不同维度时间周期的长度
        int elementsSize = AdvancedSearchUtil.getElementsSize(salePlanDirectlyDifferinDTO.getWeekDateList());
        //将整个list中元素聚合
        Map<String, BigDecimal> finalMap = map;
        Map<String, List<BigDecimal>> valuesResult = salePlanDirectlyDifferinInfoDTOs.stream().collect(Collectors.collectingAndThen(Collectors.toList(), values -> {
            //遍历每一组的集合，将对应参数聚合，然后赋值给第一个元素，将第一个元素返回
            List<BigDecimal> salesForecastAmounts = new ArrayList<>();
            List<BigDecimal> salesActualAmounts = new ArrayList<>();
            List<BigDecimal> salesActualQtys = new ArrayList<>();
            List<BigDecimal> salesForecastQtys = new ArrayList<>();
            values.forEach(item -> {
                if (finalMap.get(item.getSkuCode()) == null) {
                    throw new RomeException("999", "无法获取单位比例转换信息：" + "skuCode," + item.getSkuCode() + "; 单位类型" + SkuUnitTypeEnum.getNameByType(salePlanDirectlyDifferinDTO.getUnitType()));
                }
                salesForecastAmounts.addAll(Arrays.stream(item.getSalesForecastAmountStr().split(":")).map(BigDecimal::new).collect(Collectors.toList()));
                salesActualAmounts.addAll(Arrays.stream(item.getSalesActualAmountStr().split(":")).map(BigDecimal::new).collect(Collectors.toList()));
                salesForecastQtys.addAll(Arrays.stream(item.getSalesForecastQtyStr().split(":")).map(subItem -> new BigDecimal(subItem).divide(finalMap.get(item.getSkuCode()), 5, BigDecimal.ROUND_HALF_UP)).collect(Collectors.toList()));
                salesActualQtys.addAll(Arrays.stream(item.getSalesActualQtyStr().split(":")).map(subItem -> new BigDecimal(subItem).divide(finalMap.get(item.getSkuCode()), 5, BigDecimal.ROUND_HALF_UP)).collect(Collectors.toList()));
            });
            //总长度
            int totalSize = salesForecastAmounts.size();
            List<BigDecimal> salesForecastAmount = AdvancedSearchUtil.getMergeResult(salesForecastAmounts, elementsSize, totalSize);
            List<BigDecimal> salesActualAmount = AdvancedSearchUtil.getMergeResult(salesActualAmounts, elementsSize, totalSize);
            List<BigDecimal> salesForecastQty = AdvancedSearchUtil.getMergeResult(salesForecastQtys, elementsSize, totalSize);
            List<BigDecimal> salesActualQty = AdvancedSearchUtil.getMergeResult(salesActualQtys, elementsSize, totalSize);
            Map<String, List<BigDecimal>> result = new HashMap<>();
            result.put(SalesPlanDirectlyDifferinEnum.SALES_FORECAST_AMOUNT.getKey(), salesForecastAmount);
            result.put(SalesPlanDirectlyDifferinEnum.SALES_PLAN_AMOUNT.getKey(), salesForecastAmount);
            result.put(SalesPlanDirectlyDifferinEnum.SALES_FORECAST_QTY.getKey(), salesForecastQty);
            result.put(SalesPlanDirectlyDifferinEnum.SALES_PLAN_QTY.getKey(), salesForecastQty);
            result.put(SalesPlanDirectlyDifferinEnum.SALES_ACTUAL_AMOUNT.getKey(), salesActualAmount);
            result.put(SalesPlanDirectlyDifferinEnum.SALES_ACTUAL_QTY.getKey(), salesActualQty);
            return result;
        }));
        //判断是否需要查询GMV信息（如果需要就做处理）
        this.handelGmvInfoCharts(salePlanDirectlyDifferinDTO, valuesResult, elementsSize);
        //设置实际收货量值
        List<String> conditions = AdvancedSearchUtil.getConditions(salePlanDirectlyDifferinDTO);
        this.setActualReceivedQtyCharts(salePlanDirectlyDifferinDTO, conditions, valuesResult, elementsSize);
        EChartsExpandDTO eChartsDTO = new EChartsExpandDTO();
        eChartsDTO.setDateList(MyDateUtil.processCyclesDate(salePlanDirectlyDifferinDTO.getWeekDateList(), "M.dd"));
        if (salePlanDirectlyDifferinDTO.getValidGmv()) {
            eChartsDTO.setLabelData(this.getAllKeyLabels(SalesPlanDirectlyDifferinEnum.values()));
        } else {
            eChartsDTO.setLabelData(this.getGeneralKeyLabels(SalesPlanDirectlyDifferinEnum.values()));
        }
        eChartsDTO.setValue(valuesResult);
        eChartsDTO.setValidGmv(salePlanDirectlyDifferinDTO.getValidGmv());
        return eChartsDTO;
    }

    /**
     * 导出所有查询数据
     *
     * @param salePlanDirectlyDifferinDTO
     * @return void
     **/
    @Override
    public ExcelExportDataDTO export(SalePlanDirectlyDifferinDTO salePlanDirectlyDifferinDTO, Integer type) {
        //校验角色区域权限是否正确（同时赋值区域搜索条件）
        this.checkRoleArea(salePlanDirectlyDifferinDTO);
        //校验是否需要gmv指标
        this.checkGmv(salePlanDirectlyDifferinDTO);
        //获取mapper查询条件
        SalesPlanSelectDO salesPlanSelectDO = salePlanDirectlyDifferinSelectConvertor.dtoToDO(salePlanDirectlyDifferinDTO);
        //非分页查询
        List<SalePlanDirectlyDifferinInfoDTO> salePlanDirectlyDifferinInfoDTOs = salePlanDirectlyDifferinRepository.searchedDataExport(salesPlanSelectDO);
        if (CollectionUtils.isEmpty(salePlanDirectlyDifferinInfoDTOs)) {
            throw new RomeException(ResponseMsg.FAIL_2005.getCode(), ResponseMsg.FAIL_2005.getMsg());
        }
        //获取指标名称集合
        List<String> targets;
        if (salePlanDirectlyDifferinDTO.getValidGmv()) {
            targets = SalesPlanDirectlyDifferinEnum.getAllTargetsDesc();
        } else {
            targets = SalesPlanDirectlyDifferinEnum.getGeneralTargetsDesc();
        }
        //获取所有去重后的skuCode
        List<String> skuCodes = salePlanDirectlyDifferinInfoDTOs.stream().map(SalePlanDirectlyDifferinInfoDTO::getSkuCode).distinct().collect(Collectors.toList());
        Map<String, BigDecimal> map = this.getBaseSkuUnitRate(skuCodes, salePlanDirectlyDifferinDTO.getUnitType());
        //获取所有查询条件标识
        List<String> conditions = AdvancedSearchUtil.getConditions(salePlanDirectlyDifferinDTO);
        //获取日期标题
        List<String> dateTitles = MyDateUtil.processCyclesDate(salePlanDirectlyDifferinDTO.getWeekDateList(), "MM.dd");
        //获取excel标题 同时返回高级搜索标题的数量
        List<List<String>> heads = new ArrayList<>();
        int mergeCellsColumns = AdvancedSearchUtil.setRedirectExcelTitles(heads, conditions, dateTitles);
        //统计不同维度时间周期的长度
        int elementsSize = AdvancedSearchUtil.getElementsSize(salePlanDirectlyDifferinDTO.getWeekDateList());
        //获取excel数据
        List<List<Object>> exportDataList = new ArrayList<>();
        //处理聚合结果
        Map<String, SalePlanDirectlyDifferinInfoDTO> polymerizationResult = null;
        Map<String, BigDecimal> finalMap = map;
        List<SalePlanDirectlyDifferinInfoDTO> pageList = new ArrayList<>();
        //全部数据导出
        if (ExcelExportTypeEnum.SEARCHED_DATA_EXPORT.getType().equals(type)) {
            polymerizationResult = salePlanDirectlyDifferinInfoDTOs.stream().collect(groupingBy(item -> AdvancedSearchUtil.fetchGroupKey(item, conditions), TreeMap::new, Collectors.collectingAndThen(Collectors.toList(), values -> {
                this.handleExcelDataGroup(values, elementsSize, finalMap, conditions, salePlanDirectlyDifferinDTO.getUnitType(), pageList);
                return null;
            })));
        }
        //当前页数据导出
        if (ExcelExportTypeEnum.CURRENT_PAGE_EXPORT.getType().equals(type)) {
            //获取分页数据
            int startIndex = (salePlanDirectlyDifferinDTO.getPageNum() - 1) * salePlanDirectlyDifferinDTO.getPageSize();
            int endIndex = salePlanDirectlyDifferinDTO.getPageNum() * salePlanDirectlyDifferinDTO.getPageSize() - 1;
            //组下标
            AtomicInteger groupIndex = new AtomicInteger(0);
            polymerizationResult = salePlanDirectlyDifferinInfoDTOs.stream().collect(groupingBy(item -> AdvancedSearchUtil.fetchGroupKey(item, conditions), TreeMap::new, Collectors.collectingAndThen(Collectors.toList(), values -> {
                if (groupIndex.get() < startIndex || groupIndex.get() > endIndex) {
                    groupIndex.incrementAndGet();
                    return null;
                }
                this.handleExcelDataGroup(values, elementsSize, finalMap, conditions, salePlanDirectlyDifferinDTO.getUnitType(), pageList);
                groupIndex.incrementAndGet();
                return null;
            })));
        }
        //当前页勾选数据导出
        if (ExcelExportTypeEnum.CHECKED_BOX_EXPORT.getType().equals(type)) {
            //获取分页数据
            int startIndex = (salePlanDirectlyDifferinDTO.getPageNum() - 1) * salePlanDirectlyDifferinDTO.getPageSize();
            List<Integer> checkedIndex = salePlanDirectlyDifferinDTO.getRowIndex().stream().map(item -> item + startIndex).collect(Collectors.toList());
            //组下标
            AtomicInteger groupIndex = new AtomicInteger(0);
            polymerizationResult = salePlanDirectlyDifferinInfoDTOs.stream().collect(groupingBy(item -> AdvancedSearchUtil.fetchGroupKey(item, conditions), TreeMap::new, Collectors.collectingAndThen(Collectors.toList(), values -> {
                if (!checkedIndex.contains(groupIndex.get())) {
                    groupIndex.incrementAndGet();
                    return null;
                }
                this.handleExcelDataGroup(values, elementsSize, finalMap, conditions, salePlanDirectlyDifferinDTO.getUnitType(), pageList);
                groupIndex.incrementAndGet();
                return null;
            })));
        }
        //判断是否需要查询GMV信息（如果需要就做处理）
        this.handelGmvInfo(salePlanDirectlyDifferinDTO, pageList, elementsSize);
        //设置实际收货量值
        this.setActualReceivedQty(salePlanDirectlyDifferinDTO, conditions, pageList, elementsSize, skuCodes);
        //设置导出数据
        this.setExportDataList(exportDataList, pageList, targets, dateTitles, salePlanDirectlyDifferinDTO.getValidGmv());
        log.info("SIZE{}", polymerizationResult.size());
        return ExcelExportUtil.getExcelExportData(mergeCellsColumns, exportDataList, heads, targets.size(), new DirectlyDifferinCellWriterHandler(salePlanDirectlyDifferinDTO.getValidGmv()));
    }


    /**
     * 设置导出数据
     *
     * @param exportDataList
     * @param pageList
     * @param targets
     * @param dateTitles
     * @param isValidGmv
     * @return void
     **/
    private void setExportDataList(List<List<Object>> exportDataList, List<SalePlanDirectlyDifferinInfoDTO> pageList, List<String> targets, List<String> dateTitles, boolean isValidGmv) {
        BigDecimal zero = new BigDecimal("0");
        pageList.forEach(element -> {
            int actualIndex = 0;
            for (String target : targets) {
                List<Object> itemRow = new ArrayList<>();
                //加入，区域，品类，商品  信息
                AdvancedSearchUtil.setRedirectExcelRowAdvancedSearchCondition(element, itemRow);
                //加入指标
                itemRow.add(target);
                //加入数据
                for (int j = 0; j < dateTitles.size(); j++) {
//获取指标集合，这里没有排序，默认使用枚举的顺序
                    switch (actualIndex) {
                        case 0:
                            itemRow.add(element.getSalesForecastAmount().get(j).compareTo(zero) == 0 ? "-" : element.getSalesForecastAmount().get(j));
                            break;
                        case 1:
                            itemRow.add(element.getSalesForecastAmount().get(j).compareTo(zero) == 0 ? "-" : element.getSalesForecastAmount().get(j));
                            break;
                        case 2:
                            if (isValidGmv) {
                                if (CollectionUtils.isEmpty(element.getSalesTargetAmount())) {
                                    itemRow.add("-");
                                } else {
                                    itemRow.add(element.getSalesTargetAmount().get(j).compareTo(zero) == 0 ? "-" : element.getSalesTargetAmount().get(j));
                                }
                                break;
                            } else {
                                actualIndex++;
                            }
                        case 3:
                            itemRow.add(element.getSalesActualAmount().get(j).compareTo(zero) == 0 ? "-" : element.getSalesActualAmount().get(j));
                            break;
                        case 4:
                            itemRow.add(element.getSalesForecastQty().get(j).compareTo(zero) == 0 ? "-" : element.getSalesForecastQty().get(j));
                            break;
                        case 5:
                            itemRow.add(element.getSalesForecastQty().get(j).compareTo(zero) == 0 ? "-" : element.getSalesForecastQty().get(j));
                            break;
                        case 6:
                            itemRow.add(element.getSalesActualQty().get(j).compareTo(zero) == 0 ? "-" : element.getSalesActualQty().get(j));
                            break;
                        case 7:
                            itemRow.add(element.getActualReceivedQty().get(j).compareTo(zero) == 0 ? "-" : element.getActualReceivedQty().get(j));
                            break;
                        case 8:
                            if (isValidGmv) {
                                if (CollectionUtils.isEmpty(element.getTargetAchievementRateAmount())) {
                                    itemRow.add("-");
                                } else {
                                    itemRow.add(element.getTargetAchievementRateAmount().get(j).compareTo(zero) == 0 ? "-" : element.getTargetAchievementRateAmount().get(j));
                                }
                                break;
                            } else {
                                actualIndex++;
                            }
                        default:
                            break;
                    }

                }
                actualIndex++;
                exportDataList.add(itemRow);
            }
        });
    }

    /**
     * 处理gmv相关两个指标赋值问题(页面)
     *
     * @param salePlanDirectlyDifferinDTO
     * @param pageList
     * @param elementsSize
     * @return void
     **/
    private void handelGmvInfo(SalePlanDirectlyDifferinDTO salePlanDirectlyDifferinDTO, List<SalePlanDirectlyDifferinInfoDTO> pageList, int elementsSize) {
        if (salePlanDirectlyDifferinDTO.getValidGmv()) {
            //遍历已删选出的主要信息，获取省和大品类的搜索条件集合
            Set<String> provinceCodeList = new HashSet<>();
            Set<String> priCategoryCodeList = new HashSet<>();
            pageList.forEach(item -> {
                if (item.getProvinceCode() != null) {
                    provinceCodeList.add(item.getProvinceCode());
                }
                if (item.getPriCategoryCode() != null) {
                    priCategoryCodeList.add(item.getPriCategoryCode());
                }
            });
            SalesPlanSelectDO salesPlanSelectDO = new SalesPlanSelectDO();
            //查出所在跨14周的所有月数据
            salesPlanSelectDO.setStartTime(salePlanDirectlyDifferinDTO.getGmvStartDate());
            salesPlanSelectDO.setEndTime(salePlanDirectlyDifferinDTO.getGmvEndDate());
            salesPlanSelectDO.setProvinceCodeList(new ArrayList<>(provinceCodeList));
            salesPlanSelectDO.setPriCategoryCodeList(new ArrayList<>(priCategoryCodeList));
            List<PartOfGmvTargetInfo> partOfGmvTargetInfos = gmvTargetRepository.listPartBySelective(salesPlanSelectDO);
            //获取key-value对象
            Map<String, List<BigDecimal>> result = new HashMap<>();
            if (!CollectionUtils.isEmpty(partOfGmvTargetInfos)) {
                //每个月所在天数
                Map<Date, BigDecimal> gmvMonthDays = salePlanDirectlyDifferinDTO.getGmvMonthDays();
                //每一周所在第一个月的天数
                Map<Date, BigDecimal> weekMonthDays = salePlanDirectlyDifferinDTO.getWeekMonthDays();
                Map<Date, BigDecimal> subWeekMonthDays = salePlanDirectlyDifferinDTO.getSubWeekMonthDays();
                //每一周所在第一个月的日期
                Map<Date, Date> weekMonthDate = salePlanDirectlyDifferinDTO.getWeekMonthDate();
                Map<Date, Date> subWeekMonthDate = salePlanDirectlyDifferinDTO.getSubWeekMonthDate();
                //将其转换为：key=条件字符串   value=最终集合
                result = partOfGmvTargetInfos.stream().collect(groupingBy(item -> (item.getProvinceCode() == null ? "" : item.getProvinceCode()) + (item.getPriCategoryCode() == null ? "" : item.getPriCategoryCode()), Collectors.collectingAndThen(Collectors.toList(), values -> {
                    List<BigDecimal> list = new ArrayList<>();
                    //获得该条件下每个月的平均值
                    Map<Date, BigDecimal> itemValue = values.stream().collect(Collectors.toMap(PartOfGmvTargetInfo::getMonthStartDate, subItem -> subItem.getGmvTarget().divide(gmvMonthDays.get(subItem.getMonthStartDate()), 5, BigDecimal.ROUND_HALF_UP)));
                    salePlanDirectlyDifferinDTO.getWeekDateList().forEach(item -> {
                        Date startDate = item.get("startTime");
                        if (subWeekMonthDate.get(startDate) == null) {
                            if (itemValue.get(weekMonthDate.get(startDate)) == null) {
                                list.add(new BigDecimal("0"));
                            } else {
                                list.add(weekMonthDays.get(startDate).multiply(itemValue.get(weekMonthDate.get(startDate))).setScale(3, BigDecimal.ROUND_HALF_UP));
                            }
                        } else {
                            if (itemValue.get(weekMonthDate.get(startDate)) == null) {
                                if (itemValue.get(subWeekMonthDate.get(startDate)) == null) {
                                    list.add(new BigDecimal("0"));
                                } else {
                                    list.add(subWeekMonthDays.get(startDate).multiply(itemValue.get(subWeekMonthDate.get(startDate))).setScale(3, BigDecimal.ROUND_HALF_UP));
                                }
                            } else {
                                if (itemValue.get(subWeekMonthDate.get(startDate)) == null) {
                                    list.add(weekMonthDays.get(startDate).multiply(itemValue.get(weekMonthDate.get(startDate))).setScale(3, BigDecimal.ROUND_HALF_UP));
                                } else {
                                    list.add((weekMonthDays.get(startDate).multiply(itemValue.get(weekMonthDate.get(startDate)))).add(subWeekMonthDays.get(startDate).multiply(itemValue.get(subWeekMonthDate.get(startDate)))).setScale(3, BigDecimal.ROUND_HALF_UP));
                                }
                            }
                        }
                    });
                    return list;
                })));
            }
            Map<String, List<BigDecimal>> finalResult = result;
            pageList.forEach(item -> {
                List<BigDecimal> salesTargetAmounts = finalResult.get((item.getProvinceCode() == null ? "" : item.getProvinceCode()) + (item.getPriCategoryCode() == null ? "" : item.getPriCategoryCode()));
                if (CollectionUtils.isEmpty(salesTargetAmounts)) {
                    salesTargetAmounts = AdvancedSearchUtil.getBlankCount(elementsSize);
                }
                List<BigDecimal> targetAchievementRateAmount = AdvancedSearchUtil.getTargetAchievementRateAmount(salesTargetAmounts, item.getSalesActualAmount(), elementsSize);
                item.setTargetAchievementRateAmount(targetAchievementRateAmount);
                item.setSalesTargetAmount(salesTargetAmounts);
            });
        }
    }

    /**
     * 处理gmv相关两个指标赋值问题(图表)
     *
     * @param salePlanDirectlyDifferinDTO
     * @param valuesResult
     * @param elementsSize
     * @return void
     **/
    private void handelGmvInfoCharts(SalePlanDirectlyDifferinDTO salePlanDirectlyDifferinDTO, Map<String, List<BigDecimal>> valuesResult, int elementsSize) {
        if (salePlanDirectlyDifferinDTO.getValidGmv()) {
            //遍历已删选出的主要信息，获取省和大品类的搜索条件集合
            SalesPlanSelectDO salesPlanSelectDO = new SalesPlanSelectDO();
            //查出所在跨14周的所有月数据
            salesPlanSelectDO.setStartTime(salePlanDirectlyDifferinDTO.getGmvStartDate());
            salesPlanSelectDO.setEndTime(salePlanDirectlyDifferinDTO.getGmvEndDate());
            salesPlanSelectDO.setProvinceCodeList(salePlanDirectlyDifferinDTO.getProvinceCodeList());
            List<PartOfGmvTargetInfo> partOfGmvTargetInfos = gmvTargetRepository.listPartBySelectiveCharts(salesPlanSelectDO);
            List<BigDecimal> salesTargetAmounts;
            List<BigDecimal> result = null;
            //获取key-value对象
            if (!CollectionUtils.isEmpty(partOfGmvTargetInfos)) {
                //每个月所在天数
                Map<Date, BigDecimal> gmvMonthDays = salePlanDirectlyDifferinDTO.getGmvMonthDays();
                //每一周所在第一个月的天数
                Map<Date, BigDecimal> weekMonthDays = salePlanDirectlyDifferinDTO.getWeekMonthDays();
                Map<Date, BigDecimal> subWeekMonthDays = salePlanDirectlyDifferinDTO.getSubWeekMonthDays();
                //每一周所在第一个月的日期
                Map<Date, Date> weekMonthDate = salePlanDirectlyDifferinDTO.getWeekMonthDate();
                Map<Date, Date> subWeekMonthDate = salePlanDirectlyDifferinDTO.getSubWeekMonthDate();
                //将其转换为：key=条件字符串   value=最终集合
                result = partOfGmvTargetInfos.stream().collect(Collectors.collectingAndThen(Collectors.toList(), values -> {
                    List<BigDecimal> list = new ArrayList<>();
                    //获得该条件下每个月的平均值
                    Map<Date, BigDecimal> itemValue = values.stream().collect(Collectors.toMap(PartOfGmvTargetInfo::getMonthStartDate, subItem -> subItem.getGmvTarget().divide(gmvMonthDays.get(subItem.getMonthStartDate()), 5, BigDecimal.ROUND_HALF_UP)));
                    salePlanDirectlyDifferinDTO.getWeekDateList().forEach(item -> {
                        Date startDate = item.get("startTime");
                        if (subWeekMonthDate.get(startDate) == null) {
                            if (itemValue.get(weekMonthDate.get(startDate)) == null) {
                                list.add(new BigDecimal("0"));
                            } else {
                                list.add(weekMonthDays.get(startDate).multiply(itemValue.get(weekMonthDate.get(startDate))).setScale(3, BigDecimal.ROUND_HALF_UP));
                            }
                        } else {
                            if (itemValue.get(weekMonthDate.get(startDate)) == null) {
                                if (itemValue.get(subWeekMonthDate.get(startDate)) == null) {
                                    list.add(new BigDecimal("0"));
                                } else {
                                    list.add(subWeekMonthDays.get(startDate).multiply(itemValue.get(subWeekMonthDate.get(startDate))).setScale(3, BigDecimal.ROUND_HALF_UP));
                                }
                            } else {
                                if (itemValue.get(subWeekMonthDate.get(startDate)) == null) {
                                    list.add(weekMonthDays.get(startDate).multiply(itemValue.get(weekMonthDate.get(startDate))).setScale(3, BigDecimal.ROUND_HALF_UP));
                                } else {
                                    list.add((weekMonthDays.get(startDate).multiply(itemValue.get(weekMonthDate.get(startDate)))).add(subWeekMonthDays.get(startDate).multiply(itemValue.get(subWeekMonthDate.get(startDate)))).setScale(3, BigDecimal.ROUND_HALF_UP));
                                }
                            }
                        }
                    });
                    return list;
                }));
            }
            if (!CollectionUtils.isEmpty(result)) {
                salesTargetAmounts = result;
            } else {
                salesTargetAmounts = AdvancedSearchUtil.getBlankCount(elementsSize);
            }
            List<BigDecimal> targetAchievementRateAmount = AdvancedSearchUtil.getTargetAchievementRateAmount(salesTargetAmounts, valuesResult.get(SalesPlanDirectlyDifferinEnum.SALES_ACTUAL_AMOUNT.getKey()), elementsSize);
            valuesResult.put(SalesPlanDirectlyDifferinEnum.SALES_TARGET_AMOUNT.getKey(), salesTargetAmounts);
            valuesResult.put(SalesPlanDirectlyDifferinEnum.TARGET_ACHIEVEMENT_RATE_AMOUNT.getKey(), targetAchievementRateAmount);
        }
    }

    /**
     * 设置实际收货量值
     *
     * @param salePlanDirectlyDifferinDTO
     * @param conditions
     * @param pageList
     */
    private void setActualReceivedQty(SalePlanDirectlyDifferinDTO salePlanDirectlyDifferinDTO, List<String> conditions, List<SalePlanDirectlyDifferinInfoDTO> pageList, int elementsSize, List<String> skuCodeList) {
        PlanPoQueryDTO planPoQueryDTO = this.getPlanPoQueryDTO(salePlanDirectlyDifferinDTO, conditions, pageList, skuCodeList);
        List<PlanPoInfoDTO> planPoInfoDTOs = purchaseFacade.getReceivedQty(planPoQueryDTO);
        Map<String, List<BigDecimal>> result = new HashMap<>();
        //TODO 实际收货量改为大数据取，先置空
        planPoInfoDTOs = null;
        if (!CollectionUtils.isEmpty(planPoInfoDTOs)) {
            //skuCodes集合
            List<String> skuCodes = planPoInfoDTOs.stream().map(PlanPoInfoDTO::getSkuCode).distinct().collect(Collectors.toList());
            Map<String, BigDecimal> skuMap = this.getSkuUnitRate(skuCodes, salePlanDirectlyDifferinDTO.getUnitType());
            result = planPoInfoDTOs.stream().peek(item -> item.setCreateTime(DateUtil.beginOfWeek(item.getCreateTime()))).
                    collect(groupingBy(item ->
                                    this.fetchGroupKey(salePlanDirectlyDifferinDTO.getTerCodeMapping(), salePlanDirectlyDifferinDTO.getWarehouseArea(), item,
                                            conditions),
                            Collectors.collectingAndThen(Collectors.toList(), values -> {


                                Map<Date, BigDecimal> itemValue = values.stream().collect(groupingBy(PlanPoInfoDTO::getCreateTime,
                                        Collectors.collectingAndThen(Collectors.toList(), subValues -> {
                                            AtomicReference<BigDecimal> sum = new AtomicReference<>(new BigDecimal("0"));
                                            subValues.forEach(element -> {
                                                if (skuMap.get(element.getSkuCode()) == null) {
                                                    throw new RomeException("999", "skuCode: " + element.getSkuCode() + "; " + "unitName: " + SkuUnitTypeEnum.getNameByType(salePlanDirectlyDifferinDTO.getUnitType()) + "不存在");
                                                }
                                                sum.set(sum.get().add(element.getReceivedQty().multiply(skuMap.get(element.getSkuCode()))));
                                            });
                                            return sum.get();
                                        })));


                                List<BigDecimal> data = new ArrayList<>();
                                salePlanDirectlyDifferinDTO.getWeekDateList().forEach(element -> {
                                    Date startTime = element.get("startTime");
                                    if (itemValue.containsKey(startTime)) {
                                        data.add(itemValue.get(startTime));
                                    } else {
                                        data.add(new BigDecimal("0"));
                                    }
                                });
                                return data;
                            })));
        }


        Map<String, List<BigDecimal>> finalResult = result;
        pageList.forEach(item -> {
            List<BigDecimal> actualReceivedQty = finalResult.get(this.fetchGroupKeys(conditions, item));
            if (!CollectionUtils.isEmpty(actualReceivedQty)) {
                item.setActualReceivedQty(actualReceivedQty);
            } else {
                item.setActualReceivedQty(AdvancedSearchUtil.getBlankCount(elementsSize));
            }
        });

    }

    /**
     * 获取sku基础单位运算为其它单位的比例
     *
     * @param skuCodes
     * @param unitType
     * @return {@link Map<BigDecimal>}
     **/
    private Map<String, BigDecimal> getBaseSkuUnitRate(List<String> skuCodes, Long unitType) {
        Map<String, BigDecimal> result;
        BigDecimal bigDecimal = new BigDecimal("1");
        if (SkuUnitTypeEnum.BASIS_UNIT.getUnitType().equals(unitType)) {
            result = skuCodes.stream().collect(Collectors.toMap(item -> item, item -> bigDecimal));
        } else {
            List<SkuUnitDTO> purchaseUnitRatio = itemCoreFacade.getConversionRatio(skuCodes, unitType);
            result = purchaseUnitRatio.stream().collect(Collectors.toMap(SkuUnitDTO::getSkuCode, item -> BigDecimal.valueOf(item.getScale())));
        }
        return result;
    }

    /**
     * 获取sku采购单位运算为其它单位的比例
     *
     * @param skuCodes
     * @param unitType
     * @return {@link Map<BigDecimal>}
     **/
    private Map<String, BigDecimal> getSkuUnitRate(List<String> skuCodes, Long unitType) {
        Map<String, BigDecimal> result = new HashMap<>();
        BigDecimal bigDecimal = new BigDecimal("1");
        if (SkuUnitTypeEnum.PURCHASE_UNIT.getUnitType().equals(unitType)) {
            result = skuCodes.stream().collect(Collectors.toMap(item -> item, item -> bigDecimal));
        }
        if (SkuUnitTypeEnum.BASIS_UNIT.getUnitType().equals(unitType)) {
            List<SkuUnitDTO> purchaseUnitRatio = itemCoreFacade.getConversionRatio(skuCodes, SkuUnitTypeEnum.PURCHASE_UNIT.getUnitType());
            result = purchaseUnitRatio.stream().collect(Collectors.toMap(SkuUnitDTO::getSkuCode, item -> bigDecimal.divide(BigDecimal.valueOf(item.getScale()), 5, BigDecimal.ROUND_HALF_UP).stripTrailingZeros()));
        }
        if (SkuUnitTypeEnum.SALES_UNIT.getUnitType().equals(unitType) || SkuUnitTypeEnum.TRANSPORT_UNIT.getUnitType().equals(unitType)) {
            List<SkuUnitDTO> purchaseUnitRatio = itemCoreFacade.getConversionRatio(skuCodes, SkuUnitTypeEnum.PURCHASE_UNIT.getUnitType());
            Map<String, BigDecimal> purchaseUnitRatioMap = purchaseUnitRatio.stream().collect(Collectors.toMap(SkuUnitDTO::getSkuCode, item -> BigDecimal.valueOf(item.getScale())));
            List<SkuUnitDTO> unitRatio = itemCoreFacade.getConversionRatio(skuCodes, unitType);
            result = unitRatio.stream().collect(Collectors.toMap(SkuUnitDTO::getSkuCode, item -> {
                if (purchaseUnitRatioMap.get(item.getSkuCode()) == null) {
                    throw new RomeException("999", "skuCode: " + item.getSkuCode() + "; " + "unitName: " + SkuUnitTypeEnum.getNameByType(SkuUnitTypeEnum.PURCHASE_UNIT.getUnitType()) + "不存在");
                }
                return BigDecimal.valueOf(item.getScale()).divide(purchaseUnitRatioMap.get(item.getSkuCode()), 5, BigDecimal.ROUND_HALF_UP).stripTrailingZeros();
            }));
        }
        return result;
    }

    /**
     * 设置实际收货量值(图表)
     *
     * @param salePlanDirectlyDifferinDTO
     * @param conditions
     * @param valuesResult
     * @param elementsSize
     * @return void
     **/
    private void setActualReceivedQtyCharts(SalePlanDirectlyDifferinDTO salePlanDirectlyDifferinDTO, List<String> conditions, Map<String, List<BigDecimal>> valuesResult, int elementsSize) {
        PlanPoQueryDTO planPoQueryDTO = this.getPlanPoQueryDTO(salePlanDirectlyDifferinDTO, conditions);
        List<PlanPoInfoDTO> planPoInfoDTOs = purchaseFacade.getReceivedQty(planPoQueryDTO);
        List<BigDecimal> result = null;
        //TODO 实际收货量置空，改为从大数据取
        planPoInfoDTOs = null;
        if (!CollectionUtils.isEmpty(planPoInfoDTOs)) {
            //skuCodes集合
            List<String> skuCodes = planPoInfoDTOs.stream().map(PlanPoInfoDTO::getSkuCode).distinct().collect(Collectors.toList());
            Map<String, BigDecimal> skuMap = this.getSkuUnitRate(skuCodes, salePlanDirectlyDifferinDTO.getUnitType());
            result = planPoInfoDTOs.stream().peek(item -> item.setCreateTime(DateUtil.beginOfWeek(item.getCreateTime()))).collect(Collectors.collectingAndThen(Collectors.toList(), values -> {
                Map<Date, BigDecimal> itemValue = values.stream().collect(groupingBy(PlanPoInfoDTO::getCreateTime, Collectors.collectingAndThen(Collectors.toList(), subValues -> {
                    AtomicReference<BigDecimal> sum = new AtomicReference<>(new BigDecimal("0"));
                    subValues.forEach(element -> {
                        if (skuMap.get(element.getSkuCode()) == null) {
                            throw new RomeException("999", "skuCode: " + element.getSkuCode() + "; " + "unitName: " + SkuUnitTypeEnum.getNameByType(salePlanDirectlyDifferinDTO.getUnitType()) + "不存在");
                        }
                        sum.set(sum.get().add(element.getReceivedQty().multiply(skuMap.get(element.getSkuCode()))));
                    });
                    return sum.get();
                })));
                List<BigDecimal> data = new ArrayList<>();
                salePlanDirectlyDifferinDTO.getWeekDateList().forEach(element -> {
                    Date startTime = element.get("startTime");
                    if (itemValue.containsKey(startTime)) {
                        data.add(itemValue.get(startTime));
                    } else {
                        data.add(new BigDecimal("0"));
                    }
                });
                return data;
            }));
        }
        List<BigDecimal> actualReceivedQty;
        if (!CollectionUtils.isEmpty(result)) {
            actualReceivedQty = result;
        } else {
            actualReceivedQty = AdvancedSearchUtil.getBlankCount(elementsSize);
        }
        valuesResult.put(SalesPlanDirectlyDifferinEnum.ACTUAL_RECEIVED_QTY.getKey(), actualReceivedQty);

    }

    /**
     * 图表
     *
     * @param salePlanDirectlyDifferinDTO
     * @param conditions
     * @return
     */
    private PlanPoQueryDTO getPlanPoQueryDTO(SalePlanDirectlyDifferinDTO salePlanDirectlyDifferinDTO, List<String> conditions) {
        PlanPoQueryDTO planPoQueryDTO = new PlanPoQueryDTO();
        //设置仓库查询条件
        List<String> areaCodes = new ArrayList<>();
        if (conditions.contains(BaseSearchColumnEnum.PROVINCE_CODE.getColumn())) {
            areaCodes = salePlanDirectlyDifferinDTO.getProvinceCodeList();
        }
        if (conditions.contains(BaseSearchColumnEnum.CITY_CODE.getColumn())) {
            areaCodes = salePlanDirectlyDifferinDTO.getCityCodeList();
        }
        if (conditions.contains(BaseSearchColumnEnum.COUNTY_CODE.getColumn())) {
            areaCodes = salePlanDirectlyDifferinDTO.getCountyCodeList();
        }
        if (conditions.contains(BaseSearchColumnEnum.STORE_CODE.getColumn())) {
            areaCodes = salePlanDirectlyDifferinDTO.getStoreCodeList();
        }
        //TODO 调用远程接口获取所有的区域对应仓库编码
        List<String> warehouseCodes = new ArrayList<>();
        //TODO 获取仓库对应的区域编码
        Map<String, String> warehouseArea = new HashMap<>();
        planPoQueryDTO.setWarehouseCodes(warehouseCodes);
        salePlanDirectlyDifferinDTO.setWarehouseArea(warehouseArea);
        planPoQueryDTO.setStartTime(salePlanDirectlyDifferinDTO.getStartTime());
        planPoQueryDTO.setEndTime(DateUtil.endOfDay(salePlanDirectlyDifferinDTO.getEndTime()));
        return planPoQueryDTO;
    }

    private PlanPoQueryDTO getPlanPoQueryDTO(SalePlanDirectlyDifferinDTO salePlanDirectlyDifferinDTO, List<String> conditions, List<SalePlanDirectlyDifferinInfoDTO> pageList, List<String> skuCodeList) {
        PlanPoQueryDTO planPoQueryDTO = new PlanPoQueryDTO();
        //设置品类查询条件
        //sku
        planPoQueryDTO.setSkuCodes(skuCodeList);
        //小品类
        if (conditions.contains(BaseSearchColumnEnum.TER_CATEGORY_CODE.getColumn())) {
            planPoQueryDTO.setTerCategoryCodes(pageList.stream().map(item -> Long.valueOf(item.getTerCategoryCode())).distinct().collect(Collectors.toList()));
            salePlanDirectlyDifferinDTO.setTerCodeMapping(pageList.stream().map(BaseNormalDTO::getTerCategoryCode).distinct().collect(Collectors.toMap(Long::valueOf, item -> item)));
        }
        //中品类
        if (conditions.contains(BaseSearchColumnEnum.SEC_CATEGORY_CODE.getColumn())) {
            //获取中品类及其子品类信息
            List<CategoryBaseInfoDTO> sec = itemCoreFacade.listByCategoryCodes(pageList.stream().map(SalePlanDirectlyDifferinInfoDTO::getSecCategoryCode).distinct().collect(Collectors.toList()));
            //获取中品类id--code
            Map<Long, String> secIdCode = sec.stream().collect(Collectors.toMap(CategoryBaseInfoDTO::getId, item -> String.valueOf(item.getCode())));
            //设置小品类codes
            salePlanDirectlyDifferinDTO.setTerCodeMapping(sec.stream().map(CategoryBaseInfoDTO::getCategoryDTOList).flatMap(Collection::stream).collect(Collectors.toMap(CategoryBaseInfoDTO::getCode, item -> secIdCode.get(item.getParentId()))));
            planPoQueryDTO.setTerCategoryCodes(sec.stream().map(CategoryBaseInfoDTO::getCategoryDTOList).flatMap(Collection::stream).map(CategoryBaseInfoDTO::getCode).collect(Collectors.toList()));
        }
        //大品类
        if (conditions.contains(BaseSearchColumnEnum.PRI_CATEGORY_CODE.getColumn())) {
            //获取大品类及其中品类信息
            List<CategoryBaseInfoDTO> pri = itemCoreFacade.listByCategoryCodes(pageList.stream().map(SalePlanDirectlyDifferinInfoDTO::getPriCategoryCode).distinct().collect(Collectors.toList()));
            //获取大品类id--code
            Map<Long, String> priIdCode = pri.stream().collect(Collectors.toMap(CategoryBaseInfoDTO::getId, item -> String.valueOf(item.getCode())));
            //获取中品类及其子品类信息
            List<CategoryBaseInfoDTO> sec = itemCoreFacade.listByCategoryCodes(pri.stream().map(CategoryBaseInfoDTO::getCategoryDTOList).flatMap(Collection::stream).map(item -> String.valueOf(item.getCode())).collect(Collectors.toList()));
            //获取中品类id--code
            Map<Long, Long> secId = sec.stream().collect(Collectors.toMap(CategoryBaseInfoDTO::getId, CategoryBaseInfoDTO::getParentId));
            //设置小品类codes
            salePlanDirectlyDifferinDTO.setTerCodeMapping(sec.stream().map(CategoryBaseInfoDTO::getCategoryDTOList).flatMap(Collection::stream).collect(Collectors.toMap(CategoryBaseInfoDTO::getCode, item -> priIdCode.get(secId.get(item.getParentId())))));
            planPoQueryDTO.setTerCategoryCodes(sec.stream().map(CategoryBaseInfoDTO::getCategoryDTOList).flatMap(Collection::stream).map(CategoryBaseInfoDTO::getCode).collect(Collectors.toList()));
        }
        //TODO 调用远程接口获取所有的区域对应仓库编码
        List<String> warehouseCodes = new ArrayList<>();
        //TODO 获取仓库对应的区域编码
        Map<String, String> warehouseArea = new HashMap<>();
        //设置仓库查询条件
        List<String> areaCodes = new ArrayList<>();
        if (conditions.contains(BaseSearchColumnEnum.PROVINCE_CODE.getColumn())) {
            areaCodes = salePlanDirectlyDifferinDTO.getProvinceCodeList();
            warehouseCodes.add("X001");
            warehouseCodes.add("X002");
            warehouseCodes.add("X003");
            warehouseCodes.add("X004");
            warehouseCodes.add("X005");
            warehouseCodes.add("X006");
            warehouseArea.put("X001", "130000");
            warehouseArea.put("X002", "130000");
            warehouseArea.put("X003", "130000");
            warehouseArea.put("X004", "130000");
            warehouseArea.put("X005", "130000");
            warehouseArea.put("X006", "130000");
        }
        if (conditions.contains(BaseSearchColumnEnum.CITY_CODE.getColumn())) {
            areaCodes = salePlanDirectlyDifferinDTO.getCityCodeList();
            warehouseCodes.add("X001");
            warehouseCodes.add("X002");
            warehouseCodes.add("X003");
            warehouseArea.put("X001", "130100");
            warehouseArea.put("X002", "130100");
            warehouseArea.put("X003", "130100");
        }
        if (conditions.contains(BaseSearchColumnEnum.COUNTY_CODE.getColumn())) {
            areaCodes = salePlanDirectlyDifferinDTO.getCountyCodeList();
            warehouseCodes.add("X001");
            warehouseCodes.add("X002");
            warehouseArea.put("X001", "130104");
            warehouseArea.put("X002", "130104");
        }
        if (conditions.contains(BaseSearchColumnEnum.STORE_CODE.getColumn())) {
            areaCodes = salePlanDirectlyDifferinDTO.getStoreCodeList();
            warehouseCodes.add("X001");
            warehouseArea.put("X001", "130104002");
        }
        planPoQueryDTO.setWarehouseCodes(warehouseCodes);
        salePlanDirectlyDifferinDTO.setWarehouseArea(warehouseArea);
        planPoQueryDTO.setStartTime(salePlanDirectlyDifferinDTO.getStartTime());
        planPoQueryDTO.setEndTime(DateUtil.endOfDay(salePlanDirectlyDifferinDTO.getEndTime()));
        return planPoQueryDTO;
    }

    private String fetchGroupKeys(List<String> conditions, SalePlanDirectlyDifferinInfoDTO salePlanDirectlyDifferinInfoDTO) {
        StringBuilder groupKey = new StringBuilder();
        if (conditions == null) {
            return groupKey.toString();
        }
        //品类
        if (conditions.contains(BaseSearchColumnEnum.PRI_CATEGORY_CODE.getColumn())) {
            groupKey.append(salePlanDirectlyDifferinInfoDTO.getPriCategoryCode());
        }
        if (conditions.contains(BaseSearchColumnEnum.SEC_CATEGORY_CODE.getColumn())) {
            groupKey.append(salePlanDirectlyDifferinInfoDTO.getSecCategoryCode());
        }
        if (conditions.contains(BaseSearchColumnEnum.TER_CATEGORY_CODE.getColumn())) {
            groupKey.append(salePlanDirectlyDifferinInfoDTO.getTerCategoryCode());
        }
        if (conditions.contains(BaseSearchColumnEnum.SKU_CODE.getColumn())) {
            groupKey.append(salePlanDirectlyDifferinInfoDTO.getSkuCode());
        }
        //区域
        if (conditions.contains(BaseSearchColumnEnum.PROVINCE_CODE.getColumn())) {
            groupKey.append(salePlanDirectlyDifferinInfoDTO.getProvinceCode());
        }
        if (conditions.contains(BaseSearchColumnEnum.CITY_CODE.getColumn())) {
            groupKey.append(salePlanDirectlyDifferinInfoDTO.getCityCode());
        }
        if (conditions.contains(BaseSearchColumnEnum.COUNTY_CODE.getColumn())) {
            groupKey.append(salePlanDirectlyDifferinInfoDTO.getCountyCode());
        }
        if (conditions.contains(BaseSearchColumnEnum.STORE_CODE.getColumn())) {
            groupKey.append(salePlanDirectlyDifferinInfoDTO.getStoreCode());
        }
        return groupKey.toString();
    }

    private String fetchGroupKey(Map<Long, String> terIdCodeMap, Map<String, String> warehouseArea, PlanPoInfoDTO item, List<String> conditions) {
        StringBuilder groupKey = new StringBuilder();
        if (conditions == null) {
            return groupKey.toString();
        }
        //品类
        if (conditions.contains(BaseSearchColumnEnum.PRI_CATEGORY_CODE.getColumn())) {
            groupKey.append(terIdCodeMap.get(item.getCategory()));
        }
        if (conditions.contains(BaseSearchColumnEnum.SEC_CATEGORY_CODE.getColumn())) {
            groupKey.append(terIdCodeMap.get(item.getCategory()));
        }
        if (conditions.contains(BaseSearchColumnEnum.TER_CATEGORY_CODE.getColumn())) {
            groupKey.append(terIdCodeMap.get(item.getCategory()));
        }
        if (conditions.contains(BaseSearchColumnEnum.SKU_CODE.getColumn())) {
            groupKey.append(item.getSkuCode());
        }
        //区域
        if (warehouseArea != null && warehouseArea.size() > 0) {
            groupKey.append(warehouseArea.get(item.getWarehouseCode()));
        }
        return groupKey.toString();
    }

    /**
     * 设置标签
     *
     * @param salePlanDirectlyDifferinInfoDTO
     * @return void
     **/
    private void setLable(SalePlanDirectlyDifferinInfoDTO salePlanDirectlyDifferinInfoDTO) {
        salePlanDirectlyDifferinInfoDTO.setSalesForecastAmountLabel(SalesPlanDirectlyDifferinEnum.SALES_FORECAST_AMOUNT.getDesc());
        salePlanDirectlyDifferinInfoDTO.setSalesPlanAmountLabel(SalesPlanDirectlyDifferinEnum.SALES_PLAN_AMOUNT.getDesc());
        salePlanDirectlyDifferinInfoDTO.setSalesTargetAmountLabel(SalesPlanDirectlyDifferinEnum.SALES_TARGET_AMOUNT.getDesc());
        salePlanDirectlyDifferinInfoDTO.setSalesForecastQtyLabel(SalesPlanDirectlyDifferinEnum.SALES_FORECAST_QTY.getDesc());
        salePlanDirectlyDifferinInfoDTO.setSalesPlanQtyLabel(SalesPlanDirectlyDifferinEnum.SALES_PLAN_QTY.getDesc());
        salePlanDirectlyDifferinInfoDTO.setActualReceivedQtyLabel(SalesPlanDirectlyDifferinEnum.ACTUAL_RECEIVED_QTY.getDesc());
        salePlanDirectlyDifferinInfoDTO.setTargetAchievementRateAmountLabel(SalesPlanDirectlyDifferinEnum.TARGET_ACHIEVEMENT_RATE_AMOUNT.getDesc());
        salePlanDirectlyDifferinInfoDTO.setSalesActualAmountLabel(SalesPlanDirectlyDifferinEnum.SALES_ACTUAL_AMOUNT.getDesc());
        salePlanDirectlyDifferinInfoDTO.setSalesActualQtyLabel(SalesPlanDirectlyDifferinEnum.SALES_ACTUAL_QTY.getDesc());
    }

    private List<EChartsDTOLabelDataDTO> getGeneralKeyLabels(SalesPlanDirectlyDifferinEnum[] values) {
        List<EChartsDTOLabelDataDTO> list = new ArrayList<>();
        for (SalesPlanDirectlyDifferinEnum value : values) {
            if (value == SalesPlanDirectlyDifferinEnum.SALES_TARGET_AMOUNT || value == SalesPlanDirectlyDifferinEnum.TARGET_ACHIEVEMENT_RATE_AMOUNT) {
                continue;
            }
            EChartsDTOLabelDataDTO eChartsDTOLabelDataDTO = new EChartsDTOLabelDataDTO();
            eChartsDTOLabelDataDTO.setKey(value.getKey());
            eChartsDTOLabelDataDTO.setLabel(value.getDesc());
            list.add(eChartsDTOLabelDataDTO);
        }
        return list;
    }

    private List<EChartsDTOLabelDataDTO> getAllKeyLabels(SalesPlanDirectlyDifferinEnum[] values) {
        List<EChartsDTOLabelDataDTO> list = new ArrayList<>();
        for (SalesPlanDirectlyDifferinEnum value : values) {
            EChartsDTOLabelDataDTO eChartsDTOLabelDataDTO = new EChartsDTOLabelDataDTO();
            eChartsDTOLabelDataDTO.setKey(value.getKey());
            eChartsDTOLabelDataDTO.setLabel(value.getDesc());
            list.add(eChartsDTOLabelDataDTO);
        }
        return list;
    }

    /**
     * 导出前获取数据
     *
     * @param values
     * @param elementsSize
     * @param map
     * @param conditions
     * @param unit
     * @param pageList
     * @return void
     **/
    private void handleExcelDataGroup(List<SalePlanDirectlyDifferinInfoDTO> values, int elementsSize, Map<String, BigDecimal> map, List<String> conditions, Long unit, List<SalePlanDirectlyDifferinInfoDTO> pageList) {
        //遍历每一组的集合，将对应参数聚合，然后赋值给第一个元素，将第一个元素返回
        List<BigDecimal> salesForecastAmounts = new ArrayList<>();
        List<BigDecimal> salesActualAmounts = new ArrayList<>();
        List<BigDecimal> salesActualQtys = new ArrayList<>();
        List<BigDecimal> salesForecastQtys = new ArrayList<>();
        values.forEach(item -> {
            if (map.get(item.getSkuCode()) == null) {
                throw new RomeException("999", "无法获取单位比例转换信息：" + "skuCode," + item.getSkuCode() + "; 单位类型" + SkuUnitTypeEnum.getNameByType(unit));
            }
            salesForecastAmounts.addAll(Arrays.stream(item.getSalesForecastAmountStr().split(":")).map(BigDecimal::new).collect(Collectors.toList()));
            salesActualAmounts.addAll(Arrays.stream(item.getSalesActualAmountStr().split(":")).map(BigDecimal::new).collect(Collectors.toList()));
            salesForecastQtys.addAll(Arrays.stream(item.getSalesForecastQtyStr().split(":")).map(subItem -> new BigDecimal(subItem).divide(map.get(item.getSkuCode()), 5, BigDecimal.ROUND_HALF_UP)).collect(Collectors.toList()));
            salesActualQtys.addAll(Arrays.stream(item.getSalesActualQtyStr().split(":")).map(subItem -> new BigDecimal(subItem).divide(map.get(item.getSkuCode()), 5, BigDecimal.ROUND_HALF_UP)).collect(Collectors.toList()));
        });
        //总长度
        int totalSize = salesForecastAmounts.size();
        List<BigDecimal> salesForecastAmount = AdvancedSearchUtil.getMergeResult(salesForecastAmounts, elementsSize, totalSize);
        List<BigDecimal> salesActualAmount = AdvancedSearchUtil.getMergeResult(salesActualAmounts, elementsSize, totalSize);
        List<BigDecimal> salesForecastQty = AdvancedSearchUtil.getMergeResult(salesForecastQtys, elementsSize, totalSize);
        List<BigDecimal> salesActualQty = AdvancedSearchUtil.getMergeResult(salesActualQtys, elementsSize, totalSize);
        values.get(0).setSalesForecastAmount(salesForecastAmount);
        values.get(0).setSalesPlanAmount(salesForecastAmount);
        values.get(0).setSalesActualAmount(salesActualAmount);
        values.get(0).setSalesForecastQty(salesForecastQty);
        values.get(0).setSalesPlanQty(salesForecastQty);
        values.get(0).setSalesActualQty(salesActualQty);
        //赋值查询条件
        AdvancedSearchUtil.setGroupAdvancedSearchCondition(values.get(0), conditions);
        pageList.add(values.get(0));
    }
    @Transactional(rollbackFor = Exception.class)
    public void handleBigData(List<DirectlyDifferinInDO> differinInDOs, String storeCode) {
        salePlanDirectlyDifferinRepository.batchDeleteByStartDate(storeCode, weekStartDate);
        if (!CollectionUtils.isEmpty(differinInDOs)) {
            List<List<DirectlyDifferinInDO>> lists = splitTo(differinInDOs, 5000);
            for (List<DirectlyDifferinInDO> list : lists) {
                salePlanDirectlyDifferinRepository.batchInsert(list);
            }
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void handleRemedialBigData(List<DirectlyDifferinInDO> differinInDOs, String storeCode) {
        //删除当前日期之后的所有数据
        salePlanDirectlyDifferinRepository.batchDeleteByStartDate(storeCode, weekStartDate);
        if (!CollectionUtils.isEmpty(differinInDOs)) {
            List<List<DirectlyDifferinInDO>> lists = splitTo(differinInDOs, 5000);
            for (List<DirectlyDifferinInDO> list : lists) {
                salePlanDirectlyDifferinRepository.batchInsert(list);
            }
        }
        //删除错误日志信息
        operationLogRecordRepository.deleteBigDataErrorLog(OperationDataEnum.DIRECTLY_DIFFERIN.getTableType(), startTime, endTime, storeCode);
    }

    @Transactional(rollbackFor = Exception.class)
    public void handleUpBigData(List<DirectlyDifferinInDO> directlyDifferinInDOs, List<DirectlyDifferinUpDO> directlyDifferinUpDOs, List<Long> ids) {
        //先删除
        if (!CollectionUtils.isEmpty(ids)) {
            salePlanDirectlyDifferinRepository.rmByIds(ids);
        }
        //更新
        if (!CollectionUtils.isEmpty(directlyDifferinUpDOs)) {
            List<List<DirectlyDifferinUpDO>> lists = splitTo(directlyDifferinUpDOs, 2000);
            for (List<DirectlyDifferinUpDO> list : lists) {
                salePlanDirectlyDifferinRepository.upByIds(list);
            }
        }
        if (!CollectionUtils.isEmpty(directlyDifferinInDOs)) {
            List<List<DirectlyDifferinInDO>> lists = splitTo(directlyDifferinInDOs, 5000);
            for (List<DirectlyDifferinInDO> list : lists) {
                salePlanDirectlyDifferinRepository.batchInsert(list);
            }
        }
    }
    @Override
    public void delete(String opSign) {
        salePlanDirectlyDifferinRepository.delete(opSign);
    }
}
